﻿/*****************************************************************//**
 * @file    FITKGraphObjectCoordinateInternal.h
 * @brief   Internal graph object for coordinate axes.
 *
 * @author  ChengHaotian (yeguangbaozi@foxmail.com)
 * @date    2024-07-29
 *********************************************************************/

#ifndef __FITKGRAPHOBJECTCOORDINATEINTERNAL_H__
#define __FITKGRAPHOBJECTCOORDINATEINTERNAL_H__

#include "FITKGraphObjectFixedSizeBase.h"

// Forward declaration
class vtkPoints;
class vtkDataSet;
class vtkUnstructuredGrid;
class vtkTextProperty;
class vtkStringArray;

class FITKGraphActor;
class FITKGraphActor2D;
class FITKCoordinateAlgorithm;

namespace Interface
{
    class FITKCoordinateSystem;
}

namespace Exchange
{
    /**
     * @brief   Internal graph object for coordinate axes.
     * @author  ChengHaotian (yeguangbaozi@foxmail.com)
     * @date    2024-07-29
     */
    class FITKGraphObjectCoordinateInternal : public FITKGraphObjectFixedSizeBase
    {
        // Regist
        FITKGraphObjectRegist(FITKGraphObjectCoordinateInternal, FITKGraphObjectFixedSizeBase);
        FITKCLASS(Exchange, FITKGraphObjectCoordinateInternal);

    public:
        /**
         * @brief   Constructor.
         * @param   caseData: The case data
         * @param   coordinate: The coordnite data object[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        FITKGraphObjectCoordinateInternal(AbaqusData::FITKDataCase* caseData, Interface::FITKCoordinateSystem* coordinate = nullptr);

        /**
         * @brief   Destructor.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        ~FITKGraphObjectCoordinateInternal();

        /**
         * @brief   Set or change the coodinate system data object.
         * @param   coordinate: The coordinate data object
         * @param   update: Whether to update the graph data[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void setCoodinateSystem(Interface::FITKCoordinateSystem* coordinate, bool update = false);

        /**
         * @brief   Set the origin points of the coodinate system.
         * @param   pointsGrid: The positions of the coordinate system
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void setCustomPositions(vtkDataSet* pointsGrid);

        /**
         * @brief   Clear the input data set.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void clear();

        /**
         * @brief   Set the color of the text and the axes grid.[override]
         * @param   color: The color
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void setColor(QColor color) override;

        /**
         * @brief   Show or hide graph object.[override]
         * @param   visibility: The visibility of graph object
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void setVisible(bool visibility) override;

        /**
         * @brief   Pre-highlight the graph actors.[override]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void preHighlight() override;

        /**
         * @brief   Highlight the interactions or constraint graph actors.[override]
         * @param   color: The given color for highlighting this time[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void highlight(QColor color = QColor()) override;

        /**
         * @brief   Dis-highlight the interactions or constraint graph actors.[override]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void disHighlight() override;

        /**
         * @brief   Update all graph actors.[override]
         * @param   forceUpdate: Force update[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void update(bool forceUpdate = false) override;

        /**
         * @brief   Update the visibility with data object's visibility.[override]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void updateVisibility() override;

        /**
         * @brief   If the graph object has relation with the given data object id.[override]
         * @param   dataObjId: The data object id
         * @return  Has relation
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        bool isRelatedTo(int dataObjId) override;

        /**
         * @brief   Set if the graph object can be picked.[override]
         * @param   isPickable: Pickable
         * @param   dim: The dimision of the pickable object( -1 means the whole graph object )[default]
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void setPickable(bool isPickable, int dim = -1) override;

        /**
         * @brief   Get the fixed sized bounds of this graph object.[override]
         * @param   The bounds size
         * @return  If the graph object has fixed sized bounds
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        bool getFixedBounds(double* bounds) override;

#ifdef QT_DEBUG
        /**
         * @brief   Simplified the graph object if necessary.[override]
         * @param   enabled: Enabled simplified flag
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void simplified(bool enabled) override;
#endif // QT_DEBUG

    private:
        /**
         * @brief   Initialize the actor and data.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void initActor();

        /**
         * @brief   Generate the graph actor with the coordinate data.
         * @param   coordinate: The coordinate data object
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void generateGraph(Interface::FITKCoordinateSystem* coordinate);

        /**
         * @brief   Update the coordinate axes.
         * @param   coordinate: The coordinate data object
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void updateAxes(Interface::FITKCoordinateSystem* coordinate);

        /**
         * @brief   Get the point coordinates with the given origin and direction.
         * @param   origin: The origin
         * @param   direc: The direction
         * @param   pt: The point coordinates
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        void getPointByOriginAndDirection(double* origin, double* direc, double* pt);

    private:
        /**
         * @brief   The axes actor.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        FITKGraphActor* m_fActor{ nullptr };

        /**
         * @brief   The scale filter for fix-size actor.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        FITKCoordinateAlgorithm* m_coordFilter{ nullptr };

        /**
         * @brief   The axes label actor.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        FITKGraphActor2D* m_fActorLabel2D{ nullptr };

        /**
         * @brief   The axes line grid data.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        vtkUnstructuredGrid* m_gridAxes{ nullptr };

        /**
         * @brief   The text property for the axes labels.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        vtkTextProperty* m_textProperty{ nullptr };

        /**
         * @brief   The custom origin of the coordinate system.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        double m_customOrigin[3]{ 0., 0., 0. };

        /**
         * @brief   The color of the graph object.
         * @author  ChengHaotian (yeguangbaozi@foxmail.com)
         * @date    2024-07-29
         */
        QColor m_customColor = Qt::yellow;

    };
}   // namespace Exchange

#endif // __FITKGRAPHOBJECTCOORDINATEINTERNAL_H__
